#pragma once
#include <string>
#include <functional>
#include<unistd.h>

#include "InetAddr.hpp"

#define ListenConnection 0
#define NormalConnection 1

class Connection;
class Reactor;
using handler_t = std::function<void(Connection *conn)>;

class Connection
{
public:
    Connection(int sockfd, int type) : _sockfd(sockfd), _type(type)
    {
    }
    void RegisterHandler(handler_t _recver, handler_t _sender, handler_t _excepter)
    {
        _handler_excepter = _excepter;
        _handler_sender = _sender;
        _handler_recver = _recver;
    }

    int Sockfd()
    {
        return _sockfd;
    }
    uint32_t Event()
    {
        return _event;
    }
    void SetEvent(uint32_t event)
    {
        _event = event;
    }
    int Type()
    {
        return _type;
    }
    void SetType(int type)
    {
        _type = type;
    }
    void SetAddr(const InetAddr &addr)
    {
        _addr = addr;
    }
    void SetReactor(Reactor *R)
    {
        _R = R;
    }
    void AppendInbuffer(char buffer[])
    {
        inbuffer += buffer;
    }
    void DiscardOutbuffer(int n)
    {
        outbuffer.erase(0, n);
    }
    std::string &Outbuffer()
    {
        return outbuffer;
    }
    std::string &Inbuffer()
    {
        return inbuffer;
    }
    void Close()
    {
        close(_sockfd);
    }

private:
    int _sockfd;
    uint32_t _event;
    std::string inbuffer;
    std::string outbuffer;
    int _type;

public:
    handler_t _handler_recver;
    handler_t _handler_sender;
    handler_t _handler_excepter;

    // 回指
    Reactor *_R;
    InetAddr _addr;
};